#include "user.h"
typedef struct
{
	MyCBFun_t CB;
	PV_Union Param;

}EXTI_CtrlStruct;

EXTI_CtrlStruct EXTICtrl[EXTI_LINE_MAX];

void EXTI_Init(void)
{
#if ( (defined STM32F0) || (defined STM32L0) )
	HAL_NVIC_SetPriority(EXTI0_1_IRQn, IRQ_MOST_HIGH_LEVEL, 0);
	NVIC_EnableIRQ(EXTI0_1_IRQn);
	HAL_NVIC_SetPriority(EXTI2_3_IRQn, IRQ_MOST_HIGH_LEVEL, 0);
	NVIC_EnableIRQ(EXTI2_3_IRQn);
	HAL_NVIC_SetPriority(EXTI4_15_IRQn, IRQ_MOST_HIGH_LEVEL, 0);
	NVIC_EnableIRQ(EXTI4_15_IRQn);
#endif
}

void EXTI_Register(GPIO_TypeDef *Port, uint8_t LineSn, uint32_t Mode, uint32_t Pull, MyCBFun_t CB, void *Param)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	uint32_t Line = LineSn;
	if (LineSn >= EXTI_LINE_MAX)
		return ;
	EXTICtrl[LineSn].CB = CB;
	EXTICtrl[LineSn].Param.p = Param;
	Line = 1 << Line;
	GPIO_InitStructure.Pin = Line;
	GPIO_InitStructure.Mode = Mode;
#if (defined STM32L0)
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
#endif
#if (defined STM32F0)
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
#endif
	GPIO_InitStructure.Alternate = 0;
	GPIO_InitStructure.Pull = Pull;
	HAL_GPIO_Init(Port, &GPIO_InitStructure);
	LL_EXTI_DisableEvent_0_31(Line);
	LL_EXTI_DisableIT_0_31(Line);
}

void EXTI_OnOff(uint8_t LineSn, uint8_t OnOff)
{
	uint32_t Pin = (1UL) << LineSn;
	if (LineSn >= EXTI_LINE_MAX)
		return ;
	if (OnOff)
	{
		LL_EXTI_ClearFlag_0_31(Pin);
		LL_EXTI_EnableIT_0_31(Pin);
	}
	else
	{
		LL_EXTI_DisableEvent_0_31(Pin);
		LL_EXTI_DisableIT_0_31(Pin);
	}
}

void EXTI_IRQHandler(uint32_t StartSn, uint32_t EndSn)
{
	uint32_t Line, Temp;
	for(Line = StartSn; Line <= EndSn; Line++)
	{
		Temp = 1 << Line;
		if (LL_EXTI_ReadFlag_0_31(Temp))
		{
			LL_EXTI_ClearFlag_0_31(Temp);
			if (EXTICtrl[Line].CB)
			{
				EXTICtrl[Line].CB(EXTICtrl[Line].Param);
			}
		}
	}
}

#if ( (defined STM32F0) || (defined STM32L0) )
void EXTI0_1_IRQHandler(void)
{
	EXTI_IRQHandler(0, 1);
}
void EXTI2_3_IRQHandler(void)
{
	EXTI_IRQHandler(2, 3);
}
void EXTI4_15_IRQHandler(void)
{
	EXTI_IRQHandler(4, 15);
}
#endif
